package core

import (
	"time"
	"strconv"
	"bytes"
	"crypto/sha256"
)

// Block keeps block headers
type Block struct {
	Timestamp    int64  // 区块时间戳
	PreBlockHash []byte // 上个区块哈希值
	Hash         []byte // 当前区块哈希值
	Data         []byte // 区块包含数据
	Nonce        int
}

//newBlock creates and return Blcok
func NewBlock(data string, preBlockHash []byte) *Block {
	block := &Block{time.Now().Unix(), []byte(data), preBlockHash, []byte(data), 1}

	pow := NewProofOfWork(block)
	nonce, hash := pow.Run()

	block.Hash = hash[:]
	block.Nonce = nonce

	block.SetHash()
	return block
}

// setHash calculates and sets block hash
func (b *Block) SetHash() {
	timestamp := []byte(strconv.FormatInt(b.Timestamp, 10))
	headers := bytes.Join([][]byte{b.PreBlockHash, b.Data, timestamp}, []byte{})
	hash := sha256.Sum256(headers)
	b.Hash = hash[:]
}

// newGensisBlock creates and return genesis Block
func NewGenesisBlock() *Block {
	return NewBlock("Genesis Block", []byte{})
}
